/*
 * Created: Author: Aléx Carvalho / Date: Jan 28, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-11 04:01:39 +0000 (Thu, 11 Jun 2015) $
 */
package com.cpm.repository.jpa;

import com.cpm.ServiceLocator;
import com.cpm.entities.Folder;
import com.cpm.entities.Folder_;
import com.cpm.entities.Indicator;
import com.cpm.entities.Indicator_;
import com.cpm.entities.Node_;
import com.cpm.repository.FolderRepository;
import com.cpm.wrapper.Performance;
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import javax.persistence.Query;

public class FolderRepositoryJpa extends GenericCrudRepositoryJpa<Folder> implements FolderRepository {

    @Override
    public Performance calculePerformance(Folder parent) {
        String sqlIndicator = "SELECT (SUM(" + Indicator_.weight.getName() + "*" + Indicator_.performance.getName() + ")/SUM(" + Indicator_.weight.getName() + ")) FROM "
                + Indicator.class.getSimpleName()
                + " WHERE " + Node_.parentId.getName() + " = " + parent.getId()
                + " AND " + Node_.parentFamily.getName() + " = " + parent.getFamily().getId()
                + " AND " + Node_.performance.getName() + " IS NOT NULL";

        Query queryIndicator = entityManager.createQuery(sqlIndicator);

        Number indicatorsValue = (Number) queryIndicator.getSingleResult();

        Performance performanceIndicators = indicatorsValue != null ? new Performance(indicatorsValue.floatValue()) : null;

        List<Folder> folders = ServiceLocator.getFilter().andEquals(Folder_.parentFamily, parent.getFamily())
                .andEquals(Folder_.parentId, parent.getId()).getResultList(Folder.class);

        List<Performance> performances = new ArrayList<>();
        performances.add(performanceIndicators);
        performances.addAll(folders.stream().filter(f -> f.getPerformance() != null && f.getPerformance().getValue() != null)
                .map((Folder t) -> t.getPerformance()).collect(Collectors.toList()));

        OptionalDouble va = performances.stream().filter(p -> p != null).mapToDouble(p -> p.getValue()).average();

        if (va.isPresent()) {
            return new Performance(new Double(va.getAsDouble()).floatValue());
        }

        return null;
    }

}
